package com.quick.develop.flowable.framework.cmd;

import cn.hutool.core.map.MapUtil;
import com.quick.develop.flowable.constant.BpmConstants;
import com.quick.develop.flowable.utils.BpmTaskUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.*;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.task.Comment;
import org.flowable.task.service.HistoricTaskService;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.flowable.variable.api.history.HistoricVariableInstance;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * desc: 完善待办任务
 *
 * @author junyuan.liu
 * @date 2023/12/27 10:27
 */
@Slf4j
public class ComplementHistoricTaskCmd implements Command<Void>, Serializable {

    protected String taskId;


    public ComplementHistoricTaskCmd(String taskId) {
        this.taskId = taskId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        try {
            HistoricTaskService historicTaskService = CommandContextUtil.getHistoricTaskService(commandContext);
            HistoricTaskInstanceEntity historicTask = historicTaskService.getHistoricTask(taskId);
            Optional.ofNullable(historicTask).ifPresent(t -> {
                buildHisTask(t, commandContext);
                historicTaskService.updateHistoricTask(t, false);
            });
        } catch (Exception e) {
            log.error("已办任务:{}数据完善异常:{}", taskId, e.getMessage(), e);
        }

        return null;
    }

    private void buildHisTask(HistoricTaskInstanceEntity historicTask,CommandContext commandContext) {
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        HistoryService historyService = processEngineConfiguration.getHistoryService();
        ProcessDefinitionEntityManager processDefinitionEntityManager = CommandContextUtil.getProcessDefinitionEntityManager(commandContext);
        HistoricProcessInstanceEntityManager historicProcessInstanceEntityManager = CommandContextUtil.getHistoricProcessInstanceEntityManager(commandContext);
        ProcessDefinitionEntity processDefinition = processDefinitionEntityManager.findById(historicTask.getProcessDefinitionId());
        HistoricProcessInstanceEntity historicProcessInstance = historicProcessInstanceEntityManager.findById(historicTask.getProcessInstanceId());
        List<HistoricVariableInstance> varList = historyService.createHistoricVariableInstanceQuery().processInstanceId(historicTask.getProcessInstanceId()).list();
        Map<String, Object> variables = varList.stream()
                .collect(HashMap::new,(map,item)->map.put(item.getVariableName(),item.getValue()), HashMap::putAll
                );

        String startUserName = MapUtil.getStr(variables, BpmConstants.INITIATOR_NAME);

        Map<String, String> commentMap = getComment(commandContext, historicTask.getProcessInstanceId());
        String scopType = MapUtil.getStr(commentMap, "type");
        String comment = MapUtil.getStr(commentMap, CommentEntity.TYPE_COMMENT, "");

        historicTask.setTaskDefinitionId(processDefinition.getKey());
        historicTask.setScopeId(historicProcessInstance.getBusinessKey());
        historicTask.setSubScopeId(processDefinition.getCategory());
        historicTask.setScopeDefinitionId(processDefinition.getName());
//        Optional.ofNullable(formCode).ifPresent(historicTask::setFormKey);
        Optional.ofNullable(scopType).ifPresent(historicTask::setScopeType);
        buildDesc(historicTask, startUserName,  comment);


    }

    private void buildDesc( HistoricTaskInstanceEntity historicTask, String startUserName , String comment) {
        String description = historicTask.getDescription();
        /*拼接流程名称*/
//        String txt = BpmTaskUtil.concatDescription(description, BpmConstants.PROCESS_NAME_SP + processName);
        /*拼接流程发起者*/
        String txt = BpmTaskUtil.concatDescription(description, BpmConstants.START_USER_SP + startUserName);
        /*拼接任务审批结果*/
        txt = BpmTaskUtil.concatDescription(txt, BpmConstants.COMMENT_SP + comment);

        historicTask.setDescription(txt);

    }


    private Map<String, String> getComment(CommandContext commandContext, String processInstanceId) {
        CommentEntityManager commentEntityManager = CommandContextUtil.getCommentEntityManager(commandContext);
        HashMap<String, String> map = new HashMap<>();
        List<Comment> list =commentEntityManager.findCommentsByProcessInstanceId(processInstanceId);
        Comment comment = list.stream().filter(c -> taskId.equals(c.getTaskId())).findFirst().orElse(null);
        Optional.ofNullable(comment).ifPresent(c -> {
            map.put("type", c.getType());
            map.put(CommentEntity.TYPE_COMMENT, c.getFullMessage());
        });
        return map;
    }
}
